# views.py
import datetime
import glob
import logging
import os
import random
import time
from collections import defaultdict
from zipfile import ZipFile

import exifread
from PIL import Image
from flask import Blueprint, request, send_file

from config.load_yaml import load_config
from flask_moudle.classes.ResultMap import ResultMap
from flask_moudle.service.image_analysis import get_regeo_address, get_amap_coordinate
from flask_moudle.service.predict import instance_seg_predict


upload_file_bp = Blueprint('upload_file_bp', __name__)
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

config = load_config()
origin_path = config['path']['origin_path']
predict_path = config['path']['predict_path']
suffix_img = ['.png', '.jpg', '.jpeg']
suffix_yasuo = ['.zip', '.tar', '.7z', '.rar']
http_methods = ['GET', 'POST']


def check_suffix(filename, suffix):
    if suffix.__contains__(os.path.splitext(filename)[1]):
        return True
    else:
        return False


@upload_file_bp.route('/upload/', methods=http_methods)
def upload_file():
    # abort(500)
    file = request.files['file']
    if not check_suffix(file.filename.lower(), suffix_img):
        return ResultMap().error_message('文件格式错误')
    # 获取当前时间
    now = datetime.datetime.now()
    # 生成四位随机数
    random_number = ''.join(random.choices('0123456789', k=4))
    # 组合成字符串
    prefix = f"{now:%Y-%m-%d-%H-%M-%S}-{random_number}"
    name = prefix + os.path.splitext(file.filename)[1]
    file.save(os.path.join(origin_path, name))
    res = ResultMap().success_message_data('上传成功', name)
    return res


def support_gbk(zip_file: ZipFile):
    name_to_info = zip_file.NameToInfo
    # copy map first
    for name, info in name_to_info.copy().items():
        real_name = name.encode('cp437').decode('gbk')
        if real_name != name:
            info.filename = real_name
            del name_to_info[name]
            name_to_info[real_name] = info
    return zip_file


def dms_to_degrees(degrees, minutes, seconds):
    return float(degrees + minutes / 60 + seconds / 3600)


@upload_file_bp.route('/upload/files/', methods=http_methods)
def upload_files():
    file = request.files['file']
    if check_suffix(filename=file.filename, suffix=suffix_yasuo):
        with support_gbk(ZipFile(file, 'r', )) as zip_ref:
            zip_ref.extractall(origin_path)
            # 时间戳命名
            new_dir_name = str(int(time.time()))
            os.rename(os.path.join(origin_path, os.path.splitext(file.filename)[0]),
                      os.path.join(origin_path, new_dir_name))
            # 旋转90度
            # rotate_jpg(os.path.join(origin_path, new_dir_name), 180)
    else:
        return ResultMap().error_message('文件格式错误')
    image_files = glob.glob(os.path.join(origin_path, new_dir_name + '/' + '*.jpg'))
    data = []
    for filename in image_files:
        with open(filename, 'rb') as file:
            tags = exifread.process_file(file)
        longitude = tuple(tags['GPS GPSLongitude'].values)
        latitude = tuple(tags['GPS GPSLatitude'].values)
        data.append({
            'fileName': new_dir_name + '_' + os.path.basename(file.name),
            'longitude': dms_to_degrees(*longitude),
            'latitude': dms_to_degrees(*latitude),
            'altitude': float(tags['GPS GPSAltitude'].values[0]),
            'time': tags['Image DateTime'].values
        })
    return ResultMap().success_data(data)


@upload_file_bp.route('/origin_preview/<img_name>', methods=http_methods)
def get_image(img_name):
    return send_file(os.path.join(origin_path, img_name), mimetype='image/jpeg')


@upload_file_bp.route('/regional_analysis/', methods=http_methods)
def upload_files_parse():
    file = request.files['file']
    if check_suffix(filename=file.filename, suffix=suffix_yasuo):
        with support_gbk(ZipFile(file, 'r', )) as zip_ref:
            zip_ref.extractall(origin_path)
            # 时间戳命名
            new_dir_name = str(int(time.time()))
            os.rename(os.path.join(origin_path, os.path.splitext(file.filename)[0]),
                      os.path.join(origin_path, new_dir_name))
            # 旋转90度
            # rotate_jpg(os.path.join(origin_path, new_dir_name), 180)
    else:
        return ResultMap().error_message('文件格式错误')
    image_files = glob.glob(os.path.join(origin_path, new_dir_name + '/' + '*.jpg'))
    images_list = []
    for filename in image_files:
        with open(filename, 'rb') as file:
            tags = exifread.process_file(file)
        longitude = tuple(tags['GPS GPSLongitude'].values)
        latitude = tuple(tags['GPS GPSLatitude'].values)
        images_list.append({
            'fileName': os.path.join(new_dir_name, os.path.basename(file.name)),
            'location': get_regeo_address(
                    get_amap_coordinate(f'{dms_to_degrees(*longitude)},{dms_to_degrees(*latitude)}'))
        })
    #     .get("addressComponent").get('township')
    for image in images_list:
        blend_image, mask_image, analysis = instance_seg_predict(Image.open(os.path.join(origin_path, image.get('fileName'))))
        image['analysis']=analysis
    # 使用 defaultdict 初始化结果字典
    result = defaultdict(lambda: {
        "formatted_address": "",
        "total_analysis": {"collapse": 0, "intact": 0, "severe": 0, "slight": 0},
        "entries": []
    })

    # 遍历数据
    for item in images_list:
        township = item["location"]["formatted_address"]
        analysis = item["analysis"]

        # 更新结果字典
        result[township]["formatted_address"] = township
        result[township]["total_analysis"]["collapse"] += analysis["collapse"]
        result[township]["total_analysis"]["intact"] += analysis["intact"]
        result[township]["total_analysis"]["severe"] += analysis["severe"]
        result[township]["total_analysis"]["slight"] += analysis["slight"]
        result[township]["entries"].append(item)

    # 转换结果为列表
    final_result = list(result.values())
    return ResultMap().success_data(final_result)
